package ru.ifmo.thesis.suite;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;

import ru.ifmo.thesis.event.Event;
import ru.ifmo.thesis.event.EventListener;
import ru.ifmo.thesis.suite.SuiteRunner.NextGenerationEvolved;
import ru.ifmo.thesis.suite.SuiteRunner.TaskFinishedEvent;

public class SuiteRunnerTextFileLogger implements SuiteRunnerLogger {

	private class NextGenerationBehaviour implements EventListener {

		@Override
		public void fireEvent(Event e) {
			SuiteRunnerTextFileLogger owner = SuiteRunnerTextFileLogger.this;
			NextGenerationEvolved event = (NextGenerationEvolved) e;
			
			
			double sheduleCost = event.getSheduleCost();
			if (owner.lastSheduleCost != null && sheduleCost != owner.lastSheduleCost) {
				stagnation = 0;
			} else {
				stagnation++;
			}
			
			owner.lastSheduleCost = sheduleCost;
		}
		
	}
	
	private class TaskFinishedBehaviour implements EventListener {
		private int i = 1;
		
		@Override
		public void fireEvent(Event event) {
			output.append(String.format("%-4d, %-6d, %f\n", i, stagnation, lastSheduleCost));
			try {
				writeOutData();
			} catch (FileNotFoundException e) {
				throw new RuntimeException(e);
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
	}
	
	private Double lastSheduleCost;
	
	private int stagnation = 0;
	
	private StringBuilder output;
	
	private final String outputFileName;
	
	SuiteRunner runner;
	
	public SuiteRunnerTextFileLogger(String outputFileName, SuiteRunner runner) {
		this.output = new StringBuilder();
		this.outputFileName = outputFileName;
		this.runner = runner;
		
		output.append(String.format("%-4s, %-6s, %s\n", "NUM", "STAGN", "BEST"));
		
		runner.addEventListener(TaskFinishedEvent.NAME, new TaskFinishedBehaviour());
		runner.addEventListener(NextGenerationEvolved.NAME, new NextGenerationBehaviour());
	}
	
	
	@Override
	public void close() throws IOException {
		writeOutData();
	}


	private void writeOutData() throws FileNotFoundException, IOException {
		FileOutputStream outputStream = new FileOutputStream(outputFileName);
		Writer w = new OutputStreamWriter(outputStream);
		w.write(output.toString());
		w.close();
	}
}
